/*-------------------------------------------------
 * Adopted from IBM Developer Works article and 
 * enhanced locally for use in Worx and beyond.
 * 
 * Original Article: 
 *    http://www-128.ibm.com/developerworks/library/j-ajax1/#main
 *
 * dkc - 11/16/2005
 *	  Original port.
 *
 * dkc - 11/30/2006
 *    Added _SILK_AJAX_DEBUG_ flag for conditional
 *          debug alerts in the code.
 *-------------------------------------------------*/
var _SILK_AJAX_DEBUG_ = false;
var _FLASH_MESSAGE_ID_ = null;
var _SET_AJAX_FLAG_ = true;

//--------------------------------------------------
//	    Top Level API Calls
//--------------------------------------------------

/*************************************
 * Make the call to the server and 
 * process results throught to the
 * updateElement function which will
 * update the specified element on the
 * current page with the content that
 * was returned by the server.
 * 
 * Two flavors are supported, the first
 * uses a speficied url and args list, the
 * second extracts the submission info from 
 * a form and returns false to allow use 
 * from an onSubmit event in the form tag.
 */
function remoteUpdate(url,args,elementName) { 
	fireAJAXRequest(url,args,updateElement,elementName);
}

function remoteFormUpdate(form,elementName) { 
	remoteUpdate(form.action,formData2Args(form),elementName);
	
	return false;
}

/***************************************************
 * A little utility that waits to be sure your
 * target div is available before sending a req
 * that has nowhere to go.  Very handy for setting
 * up a div set with separate content calls. Use 
 * the remoteUdate() function to retrieve the div 
 * set and then use waitForIt() to populate each 
 * of the incoming content panels.  
 *
 * Use the optional skip parameter on original call 
 * to force a wait in case you have a div using
 * the same name on the current page and want 
 * to wait for the new div set to arrive.
 */
function waitForIt(url,divName,args,wait,skip){
	// is it there yet?
	if(document.getElementById(divName) && !skip)
		// yup, kick it!
		remoteUpdate(url,args,divName);
	else 
		// nope, take another spin
		setTimeout("waitForIt('"+url+"','"+divName+"','"+args+"',"+wait+");",wait,0);
}


//--------------------------------------------------
//	  Lower Level API Calls and AJAX mechanicals 
//--------------------------------------------------

/************************************************ 
 * Returns a new XMLHttpRequest object, or false 
 * if this browser doesn't support it
 */
function newXMLHttpRequest() {

  var xmlreq = false;

  if (window.XMLHttpRequest) {

    // Create XMLHttpRequest object in non-Microsoft browsers
    xmlreq = new XMLHttpRequest();

  } else if (window.ActiveXObject) {

    // Create XMLHttpRequest via MS ActiveX
    try {
      // Try to create XMLHttpRequest in later versions
      // of Internet Explorer

      xmlreq = new ActiveXObject("Msxml2.XMLHTTP");

    } catch (e1) {

      // Failed to create required ActiveXObject

      try {
        // Try version supported by older versions
        // of Internet Explorer

        xmlreq = new ActiveXObject("Microsoft.XMLHTTP");

      } catch (e2) {

        // Unable to create an XMLHttpRequest with ActiveX
        alert("Error: Unable to create the transger agent");
      }
    }
  }
  
  // return the AJAX transfer agent
  return xmlreq;
}

/******************************************************
 * Returns a function that waits for the specified 
 * XMLHttpRequest to complete, then passes its XML 
 * response to the given handler function.
 *
 * req - The XMLHttpRequest whose stat 								<input type="hidden" name="axtion" value="import.TypeSelect"/>
 e is changing
 * responseXmlHandler - Callback function for response
 */
function getReadyStateHandler(req, responseXmlHandler, target) {
  // Return an anonymous function that listens to the 
  // XMLHttpRequest instance
  return function () {
    // If the request's status is "complete"
    if (req.readyState == 4) {
      
      // Check that a successful server response was received
      if (req.status == 200) {

        // Pass the XML payload of the response to the 
        // handler function
        responseXmlHandler(req,target);
        
      } else {

        // An HTTP problem has occurred
        alert("HTTP error: " + req.status);
      }
    }
  }
}

/******************************************************* 
 * Facade for managing page update requests.  If this
 * called with fourth paramenter (arguments[3]), it 
 * identifies the extra data to the response processor.
 */
function fireAJAXRequest(actionUrl, reqText, respProcessor,target) { 
  // Obtain an XMLHttpRequest instance
  var req = newXMLHttpRequest();

  // Set the handler function to receive callback notifications
  // from the request object
  var handlerFunction = getReadyStateHandler(req, respProcessor,target);

  // set AJAX flag (or not)
  if (_SET_AJAX_FLAG_){
  	if (reqText.length)
  		reqText += "&";
  	reqText += "isajax=1";
  }
  
  // attach the handler to the request  
  req.onreadystatechange = handlerFunction;

  // Open an HTTP POST connection to the shopping cart servlet.
  // Third parameter specifies request is asynchronous.
  req.open("POST",actionUrl, true);

  // Specify that the body of the request contains form data
  req.setRequestHeader("Content-Type", 
                       "application/x-www-form-urlencoded");

  // Send form encoded data stating that I want to add the 
  // specified item to the cart.
  req.send(reqText);
}

//-----------------------------------------------------
// Utility functions for the AJAX results processing 
//-----------------------------------------------------

/************************************
 * Standard AJAX response to update 
 * a div with the results from the a
 * remote server request.
 */
function updateElement(results,divname){
	rv = getRemoteResponseResults(results);
	if((rv.code == 100) || (rv.code == 1)) {
		div = document.getElementById(divname);
		div.innerHTML = rv.data;
	}
}

/***************************************** 
 * Create a Postable args list from
 * the elements in a form.
 */
function formData2Args(form) { 
	args = "";
	for (e in form.elements) {
		el = form.elements[e];
		if(el.name && el.value){
			if(args != '')
				args += '&';
			aname = el.name == 'axtion' ? 'action' : el.name;
			args += aname + "=" + escape(el.value);
		}		
	}
    if (_SILK_AJAX_DEBUG_)	
        alert(args);
	return args;		
}

/******************************************** 
 * Mini API for setting auto flash messages
 */
 // enable flash messages
function flashOn(msgElementId) {
	_FLASH_MESSAGE_ID_ = msgElementId;
}

// disable flash messages
function flashOff() {
	_FLASH_MESSAGE_ID_ = null;
}

// display flash message if on
function flashMessage(msg){
	if(_FLASH_MESSAGE_ID_ == '_ALERT_') {
		alert(msg);
	}
	else if(_FLASH_MESSAGE_ID_) {
		el = document.getElementById(_FLASH_MESSAGE_ID_);
		if(el)
			el.innerHTML = msg
	}
}

// force flash message to specific destination
function flashMessageTo(msg,elId) {
	hld = _FLASH_MESSAGE_ID_;
	flashOn(elId);
	flashMessage(msg);
	flashOn(hld);
}

/***************************************** 
 * Create a wrapper for AJAX request
 * results.
 */
function getRemoteResponseResults(resp) {
	// we're using text parsing
	txt = resp.responseText;	
	rvResp = new Object();
	
	// re patterns for response xml
	codePtrn = /<ajaxResultCode>(.*)<\/ajaxResultCode>/;
	msgPtrn = /<ajaxMessage>(.*)<\/ajaxMessage>/;
	dataPtrn = /<\/?ajaxResponseBody>/;
	
	if (_SILK_AJAX_DEBUG_)
		alert(txt);
	
	try {
		// get header info
		rvResp.msg = msgPtrn.exec(txt)[1];
		if (_SILK_AJAX_DEBUG_)
			alert(rvResp.msg);
		
		rvResp.code = codePtrn.exec(txt)[1];
		if (_SILK_AJAX_DEBUG_)
			alert(rvResp.code);
		
		rvResp.data = null; 

		
		// good results begin with 1
		if(rvResp.code[0] == 1) {
			rVal = parseInt(rvResp.code);

			// test for text response (rcode should end in 1)
			if (rVal % 10 == 1) {
				// check for data element
				a = txt.split(dataPtrn);
		
				// did we get anything?
				if (a.length <= 1) 
					rvResp.data = "No Data";
				else
					rvResp.data = a[1];

				if (_SILK_AJAX_DEBUG_)
					alert(rvResp.data);	
			}
			
			
			// test for XML response (rcode = 1xx)
			tst = rVal - 100;
			if ((tst < 100) && (tst >= 0)) {
				rvResp.data = resp.responseXML;
			}				
		}						
	}
	
	catch(e) {
		rvResp.code = -1;
		rvResp.msg = 'Invalid Response';
		rvResp.data = e;
		rvResp.text = null;
		if (_SILK_AJAX_DEBUG_)
			alert('Invalid Response' + e);
	}	

	// return results object
	return rvResp;
}
